﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Text;

using D2D = Microsoft.WindowsAPICodePack.DirectX.Direct2D1;
using DI = Microsoft.WindowsAPICodePack.DirectX.WindowsImagingComponent;
using DW = Microsoft.WindowsAPICodePack.DirectX.DirectWrite;
using Paint = System.Drawing;

namespace Framework
{

    public enum AlignmentX
    {
        Left,
        Center,
        Right
    }

    public enum AlignmentY
    {
        Top,
        Center,
        Bottom
    }

    [Map("Projection")]
    [Map("PlaneProjection")]
    [Map("Matrix3D")]
    public class Projection
    {
        public double CenterOfRotationX;
        public double CenterOfRotationY;
        public double CenterOfRotationZ;
        public double GlobalOffsetX;
        public double GlobalOffsetY;
        public double GlobalOffsetZ;
        public double LocalOffsetX;
        public double LocalOffsetY;
        public double LocalOffsetZ;
        public double RotationX;
        public double RotationY;
        public double RotationZ;

        public bool HasInverse;
        public static Projection Identity;
        public bool IsIdentity;
        public double M11;
        public double M12;
        public double M13;
        public double M14;
        public double M21;
        public double M22;
        public double M23;
        public double M24;
        public double M31;
        public double M32;
        public double M33;
        public double M34;
        public double M44;
        public double OffsetX;
        public double OffsetY;
        public double OffsetZ;

    }

    public sealed class Colors
    {
        public static Color Black = Color.FromArgb(0xFF, 0x00, 0x00, 0x00);
        public static Color Blue = Color.FromArgb(0xFF, 0x00, 0x00, 0xFF);
        public static Color Brown = Color.FromArgb(0xFF, 0xA5, 0x2A, 0x2A);
        public static Color Cyan = Color.FromArgb(0xFF, 0x00, 0xFF, 0xFF);
        public static Color DarkGray = Color.FromArgb(0xFF, 0xA9, 0xA9, 0xA9);
        public static Color Gray = Color.FromArgb(0xFF, 0x80, 0x80, 0x80);
        public static Color Green = Color.FromArgb(0xFF, 0x00, 0x80, 0x00);
        public static Color LightGray = Color.FromArgb(0xFF, 0xD3, 0xD3, 0xD3);
        public static Color Magenta = Color.FromArgb(0xFF, 0xFF, 0x00, 0xFF);
        public static Color Orange = Color.FromArgb(0xFF, 0xFF, 0xA5, 0x00);
        public static Color Purple = Color.FromArgb(0xFF, 0x80, 0x00, 0x80);
        public static Color Red = Color.FromArgb(0xFF, 0xFF, 0x00, 0x00);
        public static Color Transparent = Color.FromArgb(0x00, 0xFF, 0xFF, 0xFF);
        public static Color White = Color.FromArgb(0xFF, 0xFF, 0xFF, 0xFF);
        public static Color Yellow = Color.FromArgb(0xFF, 0xFF, 0xFF, 0x00);
    }

    public enum MediaElementState
    {
        Closed,
        Opening,
        Buffering,
        Playing,
        Paused,
        Stopped,
        Individualizing,
        AcquiringLicense,
    }

    public enum FillRule
    {
        EvenOdd,
        Nonzero
    }

    public class Typeface
    {

        public Typeface(string typefaceName)
        {
            FontFamily = new FontFamily(typefaceName);
        }

        public Typeface(FontFamily fontFamily, FontStyle style, FontWeight weight, FontStretch stretch)
        {
            FontFamily = fontFamily;
            //...
        }

        public Typeface(FontFamily fontFamily, FontStyle style, FontWeight weight, FontStretch stretch, FontFamily fallbackFontFamily)
        {
            FontFamily = fontFamily;
            //...
        }

        /// <summary>
        /// 获取从字样的基线到英语大写字母顶部的距离
        /// </summary>
        public double CapsHeight
        {
            get { throw new NotImplementedException(); }
        }

        /// <summary>
        /// 获取从中构造字样的字体系列的名称
        /// </summary>
        public FontFamily FontFamily { get; internal set; }

        /// <summary>
        /// 确定是否模仿 Typeface 所表示的标志符号的粗体粗细
        /// </summary>
        public bool IsBoldSimulated
        {
            get { throw new NotImplementedException(); }
        }

        /// <summary>
        /// 确定是否模仿 Typeface 所表示的标志符号的斜体样式
        /// </summary>
        public bool IsObliqueSimulated
        {
            get { throw new NotImplementedException(); }
        }

        /// <summary>
        /// 获取 Typeface 的拉伸值。 拉伸值确定在显示字样时是扩展字样还是压缩字样。
        /// </summary>
        public FontStretch Stretch { get; internal set; }

        /// <summary>
        /// 获取一个值，该值指示从字样基线到字样删除线的距离 
        /// </summary>
        public double StrikethroughPosition
        {
            get { throw new NotImplementedException(); }
        }

        /// <summary>
        /// 获取一个值，该值指示删除线相对于字体 em 大小的宽度
        /// </summary>
        public double StrikethroughThickness
        {
            get { throw new NotImplementedException(); }
        }

        /// <summary>
        /// 获取 Typeface 的样式
        /// </summary>
        public FontStyle Style { get; internal set; }

        /// <summary>
        /// 获取一个值，该值指示字样下划线与字样基线之间的距离
        /// </summary>
        public double UnderlinePosition
        {
            get { throw new NotImplementedException(); }
        }

        /// <summary>
        ///  获取一个值，该值指示下划线相对于字样的字体 em 大小的宽度
        /// </summary>
        public double UnderlineThickness
        {
            get { throw new NotImplementedException(); }
        }

        /// <summary>
        ///  获取字样的相对粗细
        /// </summary>
        public FontWeight Weight
        {
            get { throw new NotImplementedException(); }
        }

        /// <summary>
        /// 获取从字样基线到英语小写字母顶部的距离。 此距离不包括升部
        /// </summary>
        public double XHeight
        {
            get { throw new NotImplementedException(); }
        }

    }

    public class FormattedText
    {
        public double Baseline;
        public double Extent;
        public FlowDirection FlowDirection { get; set; }
        public double Height;
        public double LineHeight { get; set; }
        public int MaxLineCount { get; set; }
        public double MaxTextHeight { get; set; }
        public double MaxTextWidth { get; set; }
        public double MinWidth { get; set; }
        public double OverhangAfter { get; set; }
        public double OverhangLeading { get; set; }
        public double OverhangTrailing { get; set; }
        public string Text { get; internal set; }
        public TextAlignment TextAlignment { get; set; }

        public TextTrimming Trimming { get; set; }
        public double Width
        {
            get { throw new NotImplementedException(); }
        }
        public double WidthIncludingTrailingWhitespace { get { throw new NotImplementedException(); } }

    }

    public class Font { }

    public class FontFamily
    {
        private string familyName;

        public FontFamily(string familyName)
        {
            this.familyName = familyName;
        }

        public string Source
        {
            get { return familyName; }
        }
    }

    public struct FontStretch
    {
        private FontStretchKind kind;

        internal FontStretch(FontStretchKind kind)
        {
            this.kind = kind;
        }

        public static bool operator ==(FontStretch left, FontStretch right)
        {
            return left.kind == right.kind;
        }

        public static bool operator !=(FontStretch left, FontStretch right)
        {
            return left.kind != right.kind;
        }

        public override bool Equals(object obj)
        {
            if (obj == null)
                return false;

            if (!(obj is FontStretch))
                return false;

            return this == (FontStretch)obj;
        }

        public override int GetHashCode()
        {
            return (int)kind;
        }

        public override string ToString()
        {
            return kind.ToString();
        }

    }

    public static class FontStretches
    {
        public static FontStretch Condensed
        {
            get { return new FontStretch(FontStretchKind.Condensed); }
        }

        public static FontStretch Expanded
        {
            get { return new FontStretch(FontStretchKind.Expanded); }
        }

        public static FontStretch ExtraCondensed
        {
            get { return new FontStretch(FontStretchKind.ExtraCondensed); }
        }

        public static FontStretch ExtraExpanded
        {
            get { return new FontStretch(FontStretchKind.ExtraExpanded); }
        }

        public static FontStretch Normal
        {
            get { return new FontStretch(FontStretchKind.Normal); }
        }

        public static FontStretch SemiCondensed
        {
            get { return new FontStretch(FontStretchKind.SemiCondensed); }
        }

        public static FontStretch SemiExpanded
        {
            get { return new FontStretch(FontStretchKind.SemiExpanded); }
        }

        public static FontStretch UltraCondensed
        {
            get { return new FontStretch(FontStretchKind.UltraCondensed); }
        }

        public static FontStretch UltraExpanded
        {
            get { return new FontStretch(FontStretchKind.UltraExpanded); }
        }
    }

    internal enum FontStretchKind
    {
        UltraCondensed = 1,
        ExtraCondensed,
        Condensed,
        SemiCondensed,
        Normal,
        SemiExpanded,
        Expanded,
        ExtraExpanded,
        UltraExpanded,
    }

    public struct FontStyle
    {
        private FontStyleKind kind;

        internal FontStyle(FontStyleKind kind)
        {
            this.kind = kind;
        }

        public static bool operator ==(FontStyle left, FontStyle right)
        {
            return left.kind == right.kind;
        }

        public static bool operator !=(FontStyle left, FontStyle right)
        {
            return left.kind != right.kind;
        }

        public override bool Equals(object obj)
        {
            if (obj == null)
                return false;

            if (!(obj is FontStyle))
                return false;

            return this == (FontStyle)obj;
        }

        public override int GetHashCode()
        {
            return (int)kind;
        }

        public override string ToString()
        {
            return kind.ToString();
        }
    }

    internal enum FontStyleKind
    {
        Normal = 0,
        Oblique = 1,
        Italic = 2
    }

    public static class FontStyles
    {
        public static FontStyle Italic
        {
            get { return new FontStyle(FontStyleKind.Italic); }
        }

        public static FontStyle Normal
        {
            get { return new FontStyle(FontStyleKind.Normal); }
        }
    }

    [Map("FontWeight|FontWeights")]
    public enum FontWeight
    {
        Thin = 100,
        ExtraLight = 200,
        Light = 300,
        Normal = 400,
        Medium = 500,
        SemiBold = 600,
        Bold = 700,
        ExtraBold = 800,
        Black = 900,
        ExtraBlack = 950,
    }


    public enum Stretch
    {
        None,
        Fill,
        Uniform,
        UniformToFill
    }

    public enum SweepDirection
    {
        Counterclockwise,
        Clockwise
    }

    #region Transform


    /// <summary>
    /// 我们将所有类型的Transform合起来
    /// </summary>
    [Map("TransformCollection|TransformGroup|CompositeTransform|MatrixTransform|RotateTransform|ScaleTransform|SkewTransform|TranslateTransform")]
    public class Transform : Base
    {
        public Matrix Matrix;

        public Transform Inverse { get; private set; }

        public virtual bool TryTransform(Point inPoint, out Point outPoint)
        {
            throw new NotImplementedException();
        }

        public virtual Rect TransformBounds(Rect rect)
        {
            throw new NotImplementedException();
        }

        public void Rotate(double Angle, double CenterX, double CenterY) { }

        public void Scale(double ScaleX, double ScaleY, double CenterX, double CenterY) { }

        public void Skew(double AngleX, double AngleY, double CenterX, double CenterY) { }

        public void Translate(double X, double Y) { }

        public void ApplyTransform(params Transform[] transforms) { }

    }
    #endregion Transform


    public abstract class Effect : Base
    {
        protected internal virtual Transform EffectMapping { get; private set; }
        public static Brush ImplicitInput { get; private set; }
    }

    public sealed class BlurEffect : Effect
    {
        static BlurEffect()
        {
            RegisterType(typeof(BlurEffect), typeof(Effect));
            RegisterProp(typeof(BlurEffect), "Radius", typeof(double), null);
        }
    }

    public sealed class DropShadowEffect : Effect
    {
        static DropShadowEffect()
        {
            RegisterType(typeof(DropShadowEffect), typeof(Effect));
            RegisterProp(typeof(DropShadowEffect), "Color", typeof(Color), null);
            RegisterProp(typeof(DropShadowEffect), "Opacity", typeof(double), null);
            RegisterProp(typeof(DropShadowEffect), "Direction", typeof(double), null);
            RegisterProp(typeof(DropShadowEffect), "BlurRadius", typeof(double), null);
            RegisterProp(typeof(DropShadowEffect), "ShadowDepth", typeof(double), null);
        }
    }


    [Map("ImageSource")]
    [Map("BitmapSource")]
    [Map("BitmapImage")]
    public class BitmapImage : Base
    {
        static BitmapImage()
        {
            RegisterType(typeof(BitmapImage));
            RegisterProp(typeof(BitmapImage), "PixelHeight", typeof(int), null);
            RegisterProp(typeof(BitmapImage), "PixelWidth", typeof(int), null);
        }

        public void SetSource(Stream streamSource)
        {
        }

        public BitmapImage()
        {
        }

        public BitmapImage(Uri uriSource)
        {
        }

        public BitmapCreateOptions CreateOptions { get; set; }
        public Uri UriSource { get; set; }
        //public event EventHandler<DownloadProgressEventArgs> DownloadProgress;
        //public event EventHandler<ExceptionRoutedEventArgs> ImageFailed;
        //public event EventHandler<RoutedEventArgs> ImageOpened;
    }

    public sealed class WriteableBitmap : BitmapImage
    {
        public WriteableBitmap(BitmapImage source)
        {
        }

        public WriteableBitmap(int width, int height)
        {
        }

        public WriteableBitmap(UIElement element, Transform transform)
        {
        }

        public int[] Pixels;

        public void Render(UIElement element, Transform transform)
        {
        }

        public void Invalidate()
        {
        }
    }

    [Flags]
    public enum BitmapCreateOptions
    {
        None = 0,
        DelayCreation = 2,
        IgnoreImageCache = 8,
    }

}
